package com.zbkj.service.service.course.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.zbkj.common.constants.IntegralRecordConstants;
import com.zbkj.common.constants.SysConfigConstants;
import com.zbkj.common.model.course.CourseProduction;
import com.zbkj.common.model.course.UserTask;
import com.zbkj.common.model.course.UserTaskLog;
import com.zbkj.common.model.user.User;
import com.zbkj.common.model.user.UserIntegralRecord;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.course.UserTaskSearchRequest;
import com.zbkj.common.response.CommonResult;
import com.zbkj.common.response.course.UserTaskResponse;
import com.zbkj.common.token.FrontTokenComponent;
import com.zbkj.service.dao.UserTaskDao;
import com.zbkj.service.service.SystemConfigService;
import com.zbkj.service.service.UserIntegralRecordService;
import com.zbkj.service.service.UserService;
import com.zbkj.service.service.course.CourseProductionService;
import com.zbkj.service.service.course.UserTaskLogService;
import com.zbkj.service.service.course.UserTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.jni.Mmap;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.rmi.server.UID;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Mr.guqianbin
 * @description UserTaskServiceImpl 接口实现
 * @date 2022-08-14
 */
@Service
@Slf4j
public class UserTaskServiceImpl extends ServiceImpl<UserTaskDao, UserTask> implements UserTaskService {

    @Resource
    private UserTaskDao dao;


    @Autowired
    private UserTaskLogService userTaskLogService;

    @Autowired
    private UserService userService;

    @Autowired
    private CourseProductionService courseProductionService;

    @Autowired
    private SystemConfigService systemConfigService;


    @Autowired
    private UserIntegralRecordService integralRecordService;
    @Autowired
    private FrontTokenComponent tokenComponet;

    /**
     * 列表
     *
     * @param request          请求参数
     * @param pageParamRequest 分页类参数
     * @return List<UserTask>
     * @author Mr.guqianbin
     * @since 2022-08-14
     */
    @Override
    public List<UserTask> getList(UserTaskSearchRequest request, PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        //带 UserTask 类的多条件查询
        LambdaQueryWrapper<UserTask> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        UserTask model = new UserTask();
        BeanUtils.copyProperties(request, model);
        lambdaQueryWrapper.setEntity(model);
        return dao.selectList(lambdaQueryWrapper);
    }

    @Override
    public List<UserTaskResponse> getTodayTask() {
        LambdaQueryWrapper<UserTask> lqw = new LambdaQueryWrapper<>();
        lqw.eq(UserTask::getIsShow, true);
        lqw.eq(UserTask::getIsDel, false);
        List<UserTask> userTasks = list(lqw);
        if (CollectionUtil.isEmpty(userTasks)) {
            return new ArrayList<>();
        }
        List<UserTaskResponse> userTaskResponses = new ArrayList<>();
        List<Integer> taskIds = userTasks.stream().map(UserTask::getId).collect(Collectors.toList());
        LambdaQueryWrapper<UserTaskLog> ulqw = new LambdaQueryWrapper<>();
        ulqw.in(UserTaskLog::getUserTaskId, taskIds);
        ulqw.eq(UserTaskLog::getUid,tokenComponet.getUserId());
        List<UserTaskLog> userTaskLogs = userTaskLogService.list(ulqw);
        if (CollectionUtil.isEmpty(userTaskLogs)) {
            userTasks.forEach(userTask -> {
                UserTaskResponse response = new UserTaskResponse();
                BeanUtil.copyProperties(userTask, response);
                response.setTaskLabel("0/" + userTask.getLimitCount());
                userTaskResponses.add(response);
            });
            return userTaskResponses;
        }
        Map<Integer, List<UserTaskLog>> userTaskLogMap = userTaskLogs.stream().collect(Collectors.groupingBy(UserTaskLog::getUserTaskId));
        userTasks.forEach(userTask -> {
            UserTaskResponse response = new UserTaskResponse();
            BeanUtil.copyProperties(userTask, response);
            if (userTaskLogMap.containsKey(userTask.getId())) {
                List<Date> dates = getBeginEndDate(userTask.getType());
                List<UserTaskLog> taskLogs = userTaskLogMap.get(userTask.getId());
                if (CollectionUtil.isEmpty(dates) && CollectionUtil.isNotEmpty(taskLogs)) {
                    response.setIsComplete(true);
                }
                int validateCount = 0;
                for (UserTaskLog userTaskLog : taskLogs) {
                    //在任务时间范围内的，已经完成任务
                    if (CollectionUtil.isNotEmpty(dates) &&
                            userTaskLog.getCreateTime().compareTo(dates.get(0)) > 0 && userTaskLog.getCreateTime().compareTo(dates.get(1)) <= 0) {
                        validateCount = validateCount + 1;
                    }
                }
//                taskLogs.forEach(taskLog -> {
//                    //在任务时间范围内的，已经完成任务
//                    if (CollectionUtil.isNotEmpty(dates) &&
//                            taskLog.getCreateTime().compareTo(dates.get(0)) > 0 && taskLog.getCreateTime().compareTo(dates.get(1)) <= 0) {
//                        response.setIsComplete(true);
//                    }
//                });
                if (validateCount >= userTask.getLimitCount()) {
                    response.setTaskLabel(userTask.getLimitCount() + "/" + userTask.getLimitCount());
                } else {
                    response.setTaskLabel(validateCount + "/" + userTask.getLimitCount());
                }
            } else {
                response.setTaskLabel("0/" + userTask.getLimitCount());
            }
            userTaskResponses.add(response);
        });
        return userTaskResponses;
    }

    @Override
    public CommonResult<Boolean> completeTask(Integer taskId) {
        Integer uid = userService.getUserIdException();
        UserTask userTask = getById(taskId);
        if (!userTask.getIsShow() || userTask.getIsDel()) {
            return CommonResult.success("该任务已下架或者删除");
        }
        List<Date> dates = getBeginEndDate(userTask.getType());
        LambdaQueryWrapper<UserTaskLog> userTaskLogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userTaskLogLambdaQueryWrapper.eq(UserTaskLog::getUserTaskId, taskId);
        userTaskLogLambdaQueryWrapper.eq(UserTaskLog::getUid, uid);
        if (CollectionUtil.isNotEmpty(dates)) {
            userTaskLogLambdaQueryWrapper.gt(UserTaskLog::getCreateTime, dates.get(0));
            userTaskLogLambdaQueryWrapper.le(UserTaskLog::getCreateTime, dates.get(1));
        }
        List<UserTaskLog> userTaskLogs = userTaskLogService.list(userTaskLogLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(userTaskLogs)) {
            return CommonResult.success(false, "你已完成该任务");
        }
        if (ObjectUtil.isEmpty(userTask)) {
            return CommonResult.success(false, "该任务不存在");
        }
        UserTaskLog taskLog = new UserTaskLog();
        taskLog.setUserTaskId(taskId);
        taskLog.setCreateTime(new Date());
        taskLog.setIntegral(userTask.getIntegral());
        taskLog.setType(userTask.getType());
        taskLog.setUid(uid);
        userTaskLogService.save(taskLog);
        //todo 增加积分

        // 增加record
        User user = userService.getInfoException();
        UserIntegralRecord productLikedRecord = integralRecordInit(taskLog, user.getIntegral());
        integralRecordService.save(productLikedRecord);
        userService.operationIntegral(user.getUid()
                , taskLog.getIntegral(), user.getIntegral(), "add");
        return CommonResult.success("完成任务成功");
    }

    @Override
    public void likeTaskComplete(Integer productionId) {

        //统计点赞和被点赞
        User user = userService.getInfoException();
        CourseProduction production = courseProductionService.getById(productionId);
        if (ObjectUtil.isEmpty(production)) {
            return;
        }
        //计算点赞用户的积分
        String likeProductionTaskIdStr = systemConfigService.getValueByKey(SysConfigConstants.CONFIG_PRODUCTION_LIKED_TASK_ID);
        Integer likeProductTaskId = Integer.parseInt(likeProductionTaskIdStr);
        UserTask likeProductTask = getById(likeProductTaskId);
        //判断任务的有效
        if (ObjectUtil.isEmpty(likeProductTask) || likeProductTask.getIsDel() || !likeProductTask.getIsShow()) {
            return;
        }
        //根据任务类型获取任务的开始结束时间
        List<Date> dates = getBeginEndDate(likeProductTask.getType());

        LambdaQueryWrapper<UserTaskLog> utlqw = new LambdaQueryWrapper<>();
        utlqw.eq(UserTaskLog::getUserTaskId, likeProductTaskId);
        utlqw.eq(UserTaskLog::getUid, user.getUid());
        if (CollectionUtil.isNotEmpty(dates)) {//如果开始结束时间为空，表明该任务是一次性任务
            utlqw.gt(UserTaskLog::getCreateTime, dates.get(0));
            utlqw.le(UserTaskLog::getCreateTime, dates.get(1));
        }
        List<UserTaskLog> userTaskLogs = userTaskLogService.list(utlqw);
        log.info("当前月份已获得的点赞字数{}", userTaskLogs.size());
        if (userTaskLogs.size() >= 25) {
            return;
        }

        UserTaskLog likeTaskLog = new UserTaskLog();
        likeTaskLog.setUserTaskId(likeProductTaskId);
        likeTaskLog.setUid(user.getUid());
        likeTaskLog.setIntegral(likeProductTask.getIntegral());
        likeTaskLog.setType(likeProductTask.getType());
        likeTaskLog.setCreateTime(new Date());
        userTaskLogService.save(likeTaskLog);
        // 增加record
        UserIntegralRecord userIntegralRecord = integralRecordInit(likeTaskLog, user.getIntegral());
        integralRecordService.save(userIntegralRecord);
        userService.operationIntegral(user.getUid(), likeProductTask.getIntegral(), user.getIntegral(), "add");

//        //计算作品被点赞者的增加积分
//        User productUser = userService.getById(production.getUid());
//        String productionLikedTaskIdStr = systemConfigService.getValueByKey(SysConfigConstants.CONFIG_PRODUCTION_LIKED_TASK_ID);
//        Integer productLikedTaskId = Integer.parseInt(productionLikedTaskIdStr);
//        UserTask productLikedTask = getById(productLikedTaskId);
//        //判断被点赞任务的有效性
//        if (ObjectUtil.isEmpty(productLikedTask) || productLikedTask.getIsDel() || !productLikedTask.getIsShow()) {
//            return;
//        }
//        dates = getBeginEndDate(productLikedTask.getType());
//
//        utlqw.clear();
//        utlqw.eq(UserTaskLog::getUserTaskId, likeProductTaskId);
//        utlqw.eq(UserTaskLog::getUid, productUser.getUid());
//        if (CollectionUtil.isNotEmpty(dates)) {//如果开始结束时间为空，表明该任务是一次性任务
//            utlqw.gt(UserTaskLog::getCreateTime, dates.get(0));
//            utlqw.le(UserTaskLog::getCreateTime, dates.get(1));
//        }
//        userTaskLogs = userTaskLogService.list(utlqw);
//        if (CollectionUtil.isNotEmpty(userTaskLogs)) {
//            return;
//        }
//
//        //todo 增加积分
//
//        UserTaskLog productLikedTaskLog = new UserTaskLog();
//        productLikedTaskLog.setUserTaskId(likeProductTaskId);
//        productLikedTaskLog.setUid(user.getUid());
//        productLikedTaskLog.setIntegral(productLikedTask.getIntegral());
//        productLikedTaskLog.setType(productLikedTask.getType());
//        productLikedTaskLog.setCreateTime(new Date());
//        userTaskLogService.save(productLikedTaskLog);
//        // 增加record
//        UserIntegralRecord productLikedRecord = integralRecordInit(productLikedTaskLog, productUser.getIntegral());
//        integralRecordService.save(productLikedRecord);
//        userService.operationIntegral(productUser.getUid()
//                , productLikedTaskLog.getIntegral(), productUser.getIntegral(), "add");

    }

    @Override
    @Transactional
    public void publicProductionTask(Integer uid) {
        User user = userService.getInfoByUid(uid);
        String publicProductionTaskIdStr = systemConfigService.getValueByKey(SysConfigConstants.CONFIG_PRODUCTION_TASK_ID);
        Integer taskId = Integer.valueOf(publicProductionTaskIdStr);
        UserTask userTask = getById(taskId);
        //判断被点赞任务的有效性
        if (ObjectUtil.isEmpty(userTask) || userTask.getIsDel() || !userTask.getIsShow()) {
            return;
        }
        //根据任务类型获取任务的开始结束时间
        List<Date> dates = getBeginEndDate(userTask.getType());

        LambdaQueryWrapper<UserTaskLog> utllqw = new LambdaQueryWrapper<>();
        utllqw.eq(UserTaskLog::getUserTaskId, taskId);
        utllqw.eq(UserTaskLog::getUid, uid);
        if (CollectionUtil.isNotEmpty(dates)) {//如果开始结束时间为空，表明该任务是一次性任务
            utllqw.gt(UserTaskLog::getCreateTime, dates.get(0));
            utllqw.le(UserTaskLog::getCreateTime, dates.get(1));
        }
        int count = userTaskLogService.count(utllqw);
        log.info("本月已上传作品数量{}", count);
        if (count > 2) {
            return;
        }
        UserTaskLog userTaskLog = new UserTaskLog();
        userTaskLog.setUserTaskId(taskId);
        userTaskLog.setCreateTime(new Date());
        userTaskLog.setIntegral(userTask.getIntegral());
        userTaskLog.setUid(uid);
        userTaskLog.setType(userTask.getType());
        userTaskLogService.save(userTaskLog);
        //增加积分变化  增加record
        UserIntegralRecord userIntegralRecord = integralRecordInit(userTaskLog, user.getIntegral());
        integralRecordService.save(userIntegralRecord);
        userService.operationIntegral(uid, userTask.getIntegral(), user.getIntegral(), "add");
    }


    /**
     * 积分添加记录
     *
     * @return UserIntegralRecord
     */
    private UserIntegralRecord integralRecordInit(UserTaskLog userTaskLog, Integer balance) {
        UserIntegralRecord integralRecord = new UserIntegralRecord();
        integralRecord.setUid(userTaskLog.getUid());
        integralRecord.setLinkId(userTaskLog.getUserTaskId().toString());
        integralRecord.setLinkType(IntegralRecordConstants.INTEGRAL_RECORD_LINK_TYPE_TASK);
        integralRecord.setType(IntegralRecordConstants.INTEGRAL_RECORD_TYPE_ADD);
        integralRecord.setTitle(IntegralRecordConstants.BROKERAGE_RECORD_TITLE_TASK);
        integralRecord.setIntegral(userTaskLog.getIntegral());
        integralRecord.setBalance(balance);
        integralRecord.setMark(StrUtil.format("用户完成任务,订单增加{}积分", userTaskLog.getIntegral()));
        integralRecord.setStatus(IntegralRecordConstants.INTEGRAL_RECORD_STATUS_COMPLETE);
        integralRecord.setFrozenTime(0);
        integralRecord.setCreateTime(com.zbkj.common.utils.DateUtil.nowDateTime());
        return integralRecord;
    }


    private List<Date> getBeginEndDate(Integer type) {

        //todo 根据任务类型获取开始结束时间
        List<Date> dates = new ArrayList<>();
        if (type == 1) {
            return dates;
        } else if (type == 2) {
            dates.add(0, DateUtil.beginOfDay(new Date()));
            dates.add(1, DateUtil.endOfDay(new Date()));
        } else if (type == 3) {
            dates.add(0, DateUtil.beginOfWeek(new Date()));
            dates.add(1, DateUtil.endOfWeek(new Date()));
        } else if (type==4) {
            dates.add(0, DateUtil.beginOfMonth(new Date()));
            dates.add(1, DateUtil.endOfMonth(new Date()));
        }
        return dates;
    }

}

